Google Cloud プロジェクトの既存リソースを Terraform コードに出力&ドキュメントを作成する方法
こんにちは、みかみです。
やりたいこと
- Google Cloud のリソースをコード管理したい
- Google Cloud プロジェクトに作成済みのリソースを Terraform のコードに出力したい
- ついでに Terraform コードからドキュメントも作っちゃいたい
前提
Google Cloud SDK(gcloud
コマンド)の実行環境は準備済みであるものとします。
本エントリでは、Cloud Shell を使用しました。
gcloud コマンドで出力
Google Cloud 公式ドキュメントによると、Google Cloud プロジェクトのリソースをコード出力する gcloud
コマンドがあるとのことです。
- Google Cloud で Terraform を使用する | Google Cloud ドキュメント
- gcloud beta resource-config bulk-export | Cloud SDK ドキュメント
まずは gcloud beta resource-config bulk-export
コマンドで、プロジェクトに作成済みのリソースを Terraform の構成ファイルに出力してみます。
出力対象の Google Cloud プロジェクトには、Cloud Storage バケットが1つと、BigQuery のデータセット&テーブルが1つある状態です。
Cloud Shell から以下のコマンドを実行しました。
gcloud beta resource-config bulk-export --resource-format=terraform --path=./bulk_export/
なお、上記コマンドの初回実行時に、google-cloud-sdk-config-connector
のインストールが必要と言われたため、apt-get
でインストール済みです。
This command requires the `config-connector` binary to be installed to export GCP resource configurations. Would you like to install the`config-connector` binary to continue command execution? (Y/n)? Y ERROR: (gcloud.beta.resource-config.bulk-export) You cannot perform this action because the Google Cloud CLI component manager is disabled for this installation. You can run the following command to achieve the same result for this installation: sudo apt-get install google-cloud-sdk-config-connector
3分ほどでコード出力が完了しました。 結果を確認してみます。
Cloud Shell Editor でみてみると、プロジェクトが所属するフォルダ ID のディレクトリと、プロジェクト番号のデイレクトリ、projects
という名前のディレクトリと、プロジェクト名のディレクトリが出力されていました。
各ディレクトリの中身も見てみます。
フォルダ ID のディレクトリの下には、請求先アカウントや所属するフォルダ ID などを定義した、プロジェクトの構成ファイルが出力されていました。
また、プロジェクト番号のデイレクトリの下には、Logging のシンク情報と有効化済みの API(サービス)の構成ファイルが出力されています。
続いて projects
ディレクトリです。配下には、BigQuery のテーブルや、サービスアカウント、Cloud Storage バケットといった、プロジェクトに属するリソースの構成ファイルがありました。
最後に、プロジェクト名のディレクトリ配下には、BigQuery データセットの構成ファイルが出力されていました。
今回はまだリソースが少ないプロジェクトだったので、どの構成ファイルがどのリソースか分かりますが、サービスアカウントや Logging のシンク情報など、明示的に作成していないリソースの構成ファイルも出力されるので、リソースが多いプロジェクトだとコード管理対象のリソースの切り分けに若干苦労しそうです。
Terraformer で出力
gcloud
コマンド以外でも、Terraform の構成ファイルを出力できる Terraformer というツールがあるようなので、こちらも使い方や出力内容を確認してみます。
以下を参考に、インストールしました。
- GoogleCloudPlatform/terraformer | GitHub
- Google Cloud ShellでTerraformerを使う | Qiita
- [GoogleCloudPlatform]から出た[terraformer]を使ってみた | Zenn
Cloud Shell で、以下のコマンドを実行します。
export PROVIDER=google curl -LO https://github.com/GoogleCloudPlatform/terraformer/releases/download/$(curl -s https://api.github.com/repos/GoogleCloudPlatform/terraformer/releases/latest | grep tag_name | cut -d '"' -f 4)/terraformer-${PROVIDER}-linux-amd64 chmod +x terraformer-${PROVIDER}-linux-amd64 sudo mv terraformer-${PROVIDER}-linux-amd64 /usr/local/bin/terraformer
--version
コマンドで確認してみると、正常にインストールできたようです。
mikami_yuki@cloudshell:~/terraform (team-da-initiative)$ terraformer --version version v0.8.19
新しく作業用ディレクトリを作成し、プラグインをインストールします。
README の記載の通り、以下の内容を versions.tf
というファイル名で保存してから、terraform init
コマンドを実行しました。
terraform { required_providers { google = { source = "hashicorp/google" } } required_version = ">= 0.13" }
これで準備完了です。以下のコマンドでコード出力を実行してみます。
terraformer import google --resources=gcs,bigQuery --projects=team-da-initiative
出力対象として GCS と BigQuery を指定しています。 指定可能なリソースは下記ドキュメントでご確認ください。
mikami_yuki@cloudshell:~/terraform/export (team-da-initiative)$ terraformer import google --resources=gcs,bigQuery --projects=team-da-initiative 2022/03/18 05:42:08 google importing project team-da-initiative region global 2022/03/18 05:42:09 googleapi: Error 404: The resource 'projects/team-da-initiative/regions/global' was not found, notFound 2022/03/18 05:42:09 googleapi: Error 404: The resource 'projects/team-da-initiative/regions/global' was not found, notFound 2022/03/18 05:42:09 google importing... gcs 2022/03/18 05:42:10 google done importing gcs 2022/03/18 05:42:10 googleapi: Error 404: The resource 'projects/team-da-initiative/regions/global' was not found, notFound 2022/03/18 05:42:10 google importing... bigQuery 2022/03/18 05:42:10 google done importing bigQuery 2022/03/18 05:42:10 Number of resources for service gcs: 6 2022/03/18 05:42:10 Number of resources for service bigQuery: 2 2022/03/18 05:42:10 Refreshing state... google_bigquery_table.tfer--team-da-initiative-003A-sample-002E-orders 2022/03/18 05:42:10 Refreshing state... google_storage_bucket_iam_member.tfer--da-initiative-recruit 2022/03/18 05:42:10 Refreshing state... google_storage_bucket.tfer--da-initiative-recruit 2022/03/18 05:42:10 Refreshing state... google_storage_bucket_acl.tfer--da-initiative-recruit 2022/03/18 05:42:10 Refreshing state... google_storage_bucket_iam_policy.tfer--da-initiative-recruit 2022/03/18 05:42:10 Refreshing state... google_storage_bucket_iam_binding.tfer--da-initiative-recruit 2022/03/18 05:42:10 Refreshing state... google_storage_default_object_acl.tfer--da-initiative-recruit 2022/03/18 05:42:10 Refreshing state... google_bigquery_dataset.tfer--team-da-initiative-003A-sample 2022/03/18 05:42:11 ERROR: Read resource response is null for resource google_storage_bucket_iam_member.tfer--da-initiative-recruit 2022/03/18 05:42:11 ERROR: Unable to refresh resource tfer--da-initiative-recruit 2022/03/18 05:42:11 Filtered number of resources for service gcs: 5 2022/03/18 05:42:11 Filtered number of resources for service bigQuery: 2 2022/03/18 05:42:11 google Connecting.... 2022/03/18 05:42:11 google save bigQuery 2022/03/18 05:42:11 google save tfstate for bigQuery 2022/03/18 05:42:11 google save gcs 2022/03/18 05:42:11 google save tfstate for gcs
なにやらエラーも出ていますが、出力完了したようです。
確認してみると
$ ls -la total 28 drwxr-xr-x 5 mikami_yuki mikami_yuki 4096 Mar 18 05:42 . drwxr-xr-x 4 mikami_yuki mikami_yuki 4096 Mar 18 05:16 .. drwxr-xr-x 3 mikami_yuki mikami_yuki 4096 Mar 18 05:42 generated drwxr-xr-x 3 mikami_yuki mikami_yuki 4096 Mar 18 05:30 .terraform -rw-r--r-- 1 mikami_yuki mikami_yuki 1080 Mar 18 05:30 .terraform.lock.hcl -rw-r--r-- 1 mikami_yuki mikami_yuki 127 Mar 18 05:30 versions.tf
generated
という名前のディレクトリが新しく作成されていました。
中身を確認してみます。
provider に指定した google ディレクトリが作成され、プロジェクト名のディレクトリが続きます。
プロジェクト名ディレクトリの下に --resources
オプションで指定したリソース名のディレクトリが作成され、その下に各リソースの構成ファイルが出力されているようです。
ファイルの中身はこんな感じ。
リソースごとにディレクトリが分かれているので、どの構成ファイルがどのリソースに関するコードなのか直感的に分かりやすい構成です。
コード内のリソース名に、プロジェクト名や 003A
などの識別子(?)的な文字列が含まれているので、別のプロジェクトに反映する場合は少しコードに手を加えた方が良さそうですが、これを使えばインフラコード管理の敷居がずいぶん低くなりそうです。
つまずいたところ
さらっと実行できたように書いていますが、実ははじめ、インストール完了後すぐに実行してしまい、以下のエラーになりました。。
$ terraformer import google --resources=gcs,bigQuery --projects=team-da-initiative 2022/03/18 05:21:53 google importing project team-da-initiative region global 2022/03/18 05:22:00 googleapi: Error 403: Compute Engine API has not been used in project 368392819661 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/compute.googleapis.com/overview?project=368392819661 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry. Details: [ { "@type": "type.googleapis.com/google.rpc.Help", "links": [ { "description": "Google developers console API activation", "url": "https://console.developers.google.com/apis/api/compute.googleapis.com/overview?project=368392819661" } ] }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "googleapis.com", "metadata": { "consumer": "projects/368392819661", "service": "compute.googleapis.com" }, "reason": "SERVICE_DISABLED" } ] , accessNotConfigured 2022/03/18 05:22:00 open /home/mikami_yuki/.terraform.d/plugins/linux_amd64: no such file or directory
エラーメッセージの通りです。。 Compute Engine API が有効になっていないことと、プラグインがインストールされていないことが原因でした。。。
terraform init
コマンドでプラグインをインストールしたら、実行できるようになりました。。
なお、Compute Engine API を有効にしなくても、GCS と BigQuery の構成ファイルは出力することができました。(エラーメッセージがうるさいので API も有効化しましたが。
Terraform のコードからドキュメントを作成
Terraform コードを管理する場合、コード内にどんなリソースが含まれるかなど、README 的なドキュメントもあるとより親切です。
ドキュメント自動作成するツールもありそうだなーと思ったら、やはりありました。
どんな準備が必要で、どんなドキュメントが出力できるのか、試してみます。
以下のコマンドを実行して terraform-docs をインストールしました。
curl -Lo ./terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.16.0/terraform-docs-v0.16.0-$(uname)-amd64.tar.gz tar -xzf terraform-docs.tar.gz chmod +x terraform-docs mv terraform-docs /usr/local/bin/terraform-docs
無事インストールできたようです。
$ terraform-docs --version terraform-docs version v0.16.0 1f686b1 linux/amd64
先ほど Terraformer で出力した GCS と BigQuery のコードに対して terraform-docs を実行して、どんな感じでドキュメント出力できるのか確認してみます。
以下のコマンドを実行しました。
terraform-docs markdown table --output-file bigQuery.md ./export/generated/google/team-da-initiative/bigQuery/global/
terraform-docs markdown table --output-file gcs.md ./export/generated/google/team-da-initiative/gcs/global/
出力結果を確認してみます。
自動出力されたコードを使ったので、リソース名がちょっとあれだったり、モジュールがないので若干さみしい感じですが、簡単にマークダウン出力することができました。 これで README も一瞬で作成できそうです。
まとめ(所感)
Terraform のコードを0から書くのは大変ですが、gcloud
コマンドや Terraformer を使えば、既存のリソースを簡単にコード出力できて便利でした。
特に Terraformer ならコード出力対象のリソースを指定できるので、検証環境のリソースに手動で変更を加えた後にコード出力して、本番環境にはコードから変更を反映するなど、リソースのコード管理が非常に楽になりそうです。
また、terraform-docs を使えば Terraform コードから簡単にマークダウンを出力することができるので、README も簡単に作成できます。
インフラのコード管理はシステム処理に直接影響するわけではないのでついつい後回しにしてしまいがちでしたが、Terraformer や terraform-docs を使えば簡単にコードやドキュメントが出力できることが分かったので、これからはありがたく利用させていただこうと思います。
参考
- Google Cloud で Terraform を使用する | Google Cloud ドキュメント
- gcloud beta resource-config bulk-export | Cloud SDK ドキュメント
- GoogleCloudPlatform/terraformer | GitHub
- GoogleCloudPlatform/terraformer/docs/gcp.md | GitHub
- Google Cloud Platform Provider| Terraform Registry
- terraform-docs/terraform-docs | GitHub
- Google Cloud ShellでTerraformerを使う | Qiita
- [GoogleCloudPlatform]から出た[terraformer]を使ってみた | Zenn
- Terraform moduleのdoc出力にはTerraform-docsを使おう | Qiita